/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.merak.core.model;

import java.io.Serializable;

import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

/**
 * Copyright © 2010-2012 Merak Computing. All rights reserved.<br><br>
 *
 * To be implemented by domain objects, including enumerated values. This class standardizes the
 * identifier naming in your project by enforcing the recommended approach of using a surrogate key
 * as primary key instead of an existent business key. It also helps to avoid composite keys.<br>
 * This class has hibernate @MappedSuperclass annotation for convenience, allowing to set the
 * identifier generation strategy in subclasses.
 *
 * @author fmarinho.
 * @param <T> The type of id property
 * @version 1.00.00 - Jul 22, 2012 - fmarinho - initial version.
 * @version 1.00.01 - Nov 28, 2012 - fmarinho - Identifiable extends Serializable; removed method getIdentifierClass.
 *
 * @since MerakCore 1.00.00
 */
@MappedSuperclass
public interface Identifiable<T extends Serializable & Comparable<T>>
		 extends Serializable
{

	//~ Methods ///////////////////////////////////////////////////////////////////
	//*****************************************************************************
	/**
	 * Returns the id of this object. The id can be null.<br>
	 * This method has hibernate @Id annotation for convenience.
	 * Annotate subclasses with @GenericGenerator(name="ID", strategy=?) to set id strategy.
	 * Annotate subclasses with @AttributeOverride(name="id", column = @Column(name=?)) if id has other name in database table.
	 * @return The id of this object. The id can be null.
	 * @since v 1.00.00
	 */
	@Id
	@GeneratedValue(generator="ID")
	public T getId();

	//*****************************************************************************
	/**
	 * Verifies if this object has an specified id. It should work for null values.
	 * @param id The value to verify.
	 * @since v 1.00.00
	 */
	public boolean hasId(T id);

	//*****************************************************************************
	/**
	 * Indicates whether objects are the exact same one; not any other. It means the objects must
	 * have same class and identifier.<br> This method differs from the equal() method, since equal
	 * domain objects may not be the same entity. Take twin siblings as example, they are equal but
	 * are identified by different names and documents.<br> Anonymous objects are never selfsame.
	 * @param object The identifiable object to compare
	 * @return true if objects have the same class and identifier; false otherwise.
	 * @since v 1.00.00
	 */
	public boolean selfsame(Identifiable<T> object) throws IdentifierException;

	//*****************************************************************************
	/**
	 * Indicates whether this object has a null id.
	 * @param object The identifiable object to compare
	 * @return true if id is null.
	 * @since v 1.00.00
	 */
	public boolean anonymous();

	//*****************************************************************************

}